package com.jxin.mall.weixin.service;

import cn.hutool.core.util.StrUtil;
import com.jxin.mall.weixin.consts.ServiceLogMsgConsts;
import com.jxin.mall.weixin.service.api.WxPortalService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.RestController;

/**
 * 微信公总号聊天窗服务实现类
 * @author  蔡佳新
 * @version 1.0
 * @since   jdk 1.8
 */
@RestController
@AllArgsConstructor
@Slf4j
public class WxPortalServiceImpl implements WxPortalService {
    /**微信服务接口*/
    private final WxMpService wxService;
    /**微信消息路由接口*/
    private final WxMpMessageRouter messageRouter;
    private static final String  ENC_TYPE = "aes";

    public String authGet(String appid,
                          String signature,
                          String timestamp,
                          String nonce,
                          String echostr) {

        log.info("接收到来自微信服务器的认证消息：[{}, {}, {}, {}]", signature,
                                                                   timestamp,
                                                                   nonce,
                                                                   echostr);
        if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
            throw new IllegalArgumentException("请求参数非法，请核实!");
        }

        if (!this.wxService.switchover(appid)) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        }

        if (wxService.checkSignature(timestamp, nonce, signature)) {
            return echostr;
        }

        return "非法请求";
    }

    public String post(String appid,
                       String requestBody,
                       String signature,
                       String timestamp,
                       String nonce,
                       String openid,
                       String encType,
                       String msgSignature) {
        if (!this.wxService.switchover(appid)) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        }

        if (!wxService.checkSignature(timestamp, nonce, signature)) {
            throw new IllegalArgumentException("非法请求，可能属于伪造的请求！");
        }
        /*获取聊天框的返回消息*/
        return getOutMsg(openid, requestBody, encType, timestamp, nonce, msgSignature);
    }


    /**
     * 获取聊天框返回消息
     * @param requestBody  请求正文
     * @param encType      加密类型
     * @param timestamp    时间截
     * @param nonce        临时参数
     * @param msgSignature 消息标记
     * @return 消息字符串
     */
    private String getOutMsg(String openid,
                            String requestBody,
                            String encType,
                            String timestamp,
                            String nonce,
                            String msgSignature) {
        log.info(WxPortalServiceMsg.REQUEST_PARAM_MSG, openid, encType, msgSignature, timestamp, nonce, requestBody);
        // 如果encType = aes
        if (ENC_TYPE.equalsIgnoreCase(encType)) {
            // aes加密的消息
            final WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody,
                                                                             wxService.getWxMpConfigStorage(),
                                                                             timestamp,
                                                                             nonce,
                                                                             msgSignature);
            if(log.isDebugEnabled()){
                log.debug(WxPortalServiceMsg.AES_DECODE_MSG, inMessage.toString());
            }
            final WxMpXmlOutMessage outMessage = getWxMpXmlOutMessage(inMessage);
            if (outMessage == null) {
                return StrUtil.EMPTY;
            }
            return outMessage.toEncryptedXml(wxService.getWxMpConfigStorage());
        }
        // 如果没有加密
        if (encType == null) {
            // 明文传输的消息
            final WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody);
            final WxMpXmlOutMessage outMessage = getWxMpXmlOutMessage(inMessage);
            if (outMessage == null) {
                return StrUtil.EMPTY;
            }
            return outMessage.toXml();
        }
        return StrUtil.EMPTY;
    }

    /**
     * 获得微信传出消息实例
     * @param message 微信传入消息
     * @return 传出消息实例 {@link WxMpXmlOutMessage}
     * @author 蔡佳新
     */
    private WxMpXmlOutMessage getWxMpXmlOutMessage(WxMpXmlMessage message) {
        try {
            return messageRouter.route(message);
        } catch (Exception e) {
            log.error(WxPortalServiceMsg.ROUTE_MSG_ERR, e);
        }
        return null;
    }
    //---------------------------------------------------logMsg---------------------------------------------------------
    /**
     * 日志信息常量的内部类
     * @author 蔡佳新
     * @version 1.0
     */
    private interface WxPortalServiceMsg{
        String  REQUEST_PARAM_MSG = ServiceLogMsgConsts.POTAL_SERVICE + ",接收微信请求:[openid=[{}], encType=[{}], msgSignature=[{}], timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ";
        String  AES_DECODE_MSG = ServiceLogMsgConsts.POTAL_SERVICE + "消息解密后内容为:{}";
        String  ROUTE_MSG_ERR = ServiceLogMsgConsts.POTAL_SERVICE + "路由消息时出现异常";

    }

}
